/**
 * 函数防抖动封装。
 * 函数防抖是一种优化策略，用于限制函数调用的频率，当一个函数频繁触发，但实际不需要每次都执行时，可以使用防抖动来节制函数的调用。
 * @param {Function} func 需要被延迟执行的函数。
 * @param {number} wait 延迟的时间间隔。
 * @param {boolean} immediate 是否在第一次调用时立即执行，默认为false，表示延迟执行。
 * @return {Function} 返回一个经过防抖处理的函数。
 */
export function debounce(func, wait, immediate) {
  // 定义变量存储延时器、函数调用的参数、上下文、时间戳和结果
  let timeout, args, context, timestamp, result;

  // 定义延时执行的函数
  const later = function() {
    // 计算距离上次触发的时间间隔
    const last = +new Date() - timestamp;

    // 判断是否需要再次延时
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 当不是立即执行模式时，调用函数
      if (!immediate) {
        result = func.apply(context, args);
        // 清理上下文和参数
        if (!timeout) context = args = null;
      }
    }
  };

  // 返回防抖函数
  return function(...args) {
    // 设置当前执行上下文和时间戳
    context = this;
    timestamp = +new Date();
    // 判断是否需要立即执行
    const callNow = immediate && !timeout;
    // 如果不存在延时器，则设置延时
    if (!timeout) timeout = setTimeout(later, wait);
    // 如果需要立即执行，则立即执行函数
    if (callNow) {
      result = func.apply(context, args);
      // 清理上下文和参数
      context = args = null;
    }

    // 返回函数执行结果
    return result;
  };
}
